<?php
/**
 * ©2013-2014. All Rights Reserved by Tranzvision, Inc.
*
* Description of CommonUtils
*
* @author hudm
*/

namespace AppBundle\Util;

use stdClass;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Serializer;

class CommonUtils
{
	/**
	 * Generate a random string with the requested length
	 *
	 * @param int $length
	 * @return string
	 */
	public static function generateUniqueCode($length = 8)
	{
		$currentTimestamp = time();
		$randomString = md5($currentTimestamp);

		return substr($randomString, 0, $length);
	}

	/**
	 * Transfer comma string to an array
	 *
	 * @param string $commaString
	 *
	 * @return array
	 */
	public static function commaString2Array($commaString)
	{
		return explode(',', $commaString);
	}

	/**
	 * @param array $array
	 *
	 * @return string
	 */
	public static function array2CommaString(array $array)
	{
		return implode(',', $array);
	}

	/**
	 * Transfer an array to object
	 *
	 * @param array $array
	 *
	 * @return stdClass
	 */
	public static function array2object($array)
	{
		if (is_array($array)) {
			$obj = new StdClass();

			foreach ($array as $key => $val) {
				$obj->$key = $val;
			}
		} else {
			$obj = $array;
		}

		return $obj;
	}

	/**
	 * Transfer a stdClass to array
	 *
	 * @param stdClass $object
	 *
	 * @return array
	 */
	public static function object2array($object)
	{
		if (is_object($object)) {
			if ($object instanceof stdClass) {
				return self::stdClass2array($object);
			} else {
				return self::stdClass2array(json_decode(self::convert2Json($object)));
			}
		} else {
			$array = $object;
		}
		return $array;
	}

	/**
	 * Transfer a stdClass to array
	 *
	 * @param $object
	 *
	 * @return mixed
	 */
	public static function stdClass2array($object)
	{
		if (is_object($object)) {
			foreach ($object as $key => $value) {
				$array[$key] = $value;
			}
		} else {
			$array = $object;
		}
		return $array;
	}

	/**
	 * Converts JSON
	 *
	 * @param mixed $obj
	 *
	 * @return string json string
	 */
	public static function convert2Json($obj)
	{
		$encoders = array(new JsonEncoder());
		$normalizers = array(new GetSetMethodNormalizer());
		$serializer = new Serializer($normalizers, $encoders);

		return $serializer->serialize($obj, 'json');
	}

	/**
	 * Get interval string for display
	 *
	 * @param \DateTime $datetime
	 * @param bool $appendix
	 *
	 * @return string interval display string
	 */
	public static function getIntervalString($datetime, $appendix = true)
	{
		$now = new \DateTime('NOW');

		$interval = $datetime->diff($now);
		//this line is printed for test only:p
		$tmp = $interval->format('%y year(s) , %m month(s) ,  %d day(s) ,  %h hour(s) ,  %i minute(s) ,  %s second(s)');
		if ($interval->y > 0) {
			return $appendix ? '1年前发布' : '1年前';
		}

		if ($interval->m > 0) {
			return $appendix ? $interval->m . '月前发布' : $interval->m . '月前';
		}

		if ($interval->d > 0) {
			return $appendix ? $interval->d . '天前发布' : $interval->d . '天前';
		}

		if ($interval->h > 0) {
			return $appendix ? $interval->h . '小时前发布' : $interval->h . '小时前';
		}

		if ($interval->i > 0) {
			return $appendix ? $interval->i . '分钟前发布' : $interval->i . '分钟前';
		}

		if ($interval->i == 0) {
			return $appendix ? '刚刚发布' : '刚刚';
		}
	}

	/**
	 * Check if the pass arguments is all filled in
	 *
	 * @return bool
	 */
	public static function mempty()
	{
		foreach (func_get_args() as $arg) {
			if (empty($arg)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Check if all of required keys have been contained in the given data
	 *
	 * @param array $required
	 * @param array $data
	 * @return bool
	 */
	public static function mKeysExistInArray(array $required, array $data)
	{
		return 0 === count(array_diff($required, array_keys($data)));
	}

	/**
	 * Check if the pass arguments is all filled in
	 *
	 * @return bool
	 */
	public static function mnull()
	{
		foreach (func_get_args() as $arg) {
			if (is_null($arg)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Convert a class to another similar class, e.g. exchanging between vo and bo
	 *
	 * @param $origin
	 * @param $newClass
	 * @param array $excluded
	 * @return mixed
	 */
	public static function convert2Other($origin, $newClass, array $excluded = array())
	{
		$stdObj = CommonUtils::convert2Json($origin);
		$stdObj = json_decode($stdObj);
		$newObj = new $newClass;

		foreach ($stdObj as $key => $value) {
			if (!in_array($key, $excluded)) {
				$setter = 'set' . ucfirst($key);
				if (is_object($value) && property_exists($value, 'timestamp')) {
					$dt = new \DateTime();
					//$dt->setTimezone('GMT'); //Or whatever
					$timestamp = $value->timestamp;
					$dt->setTimestamp($timestamp);
					$value = $dt;
				}
				if (method_exists($newObj, $setter)) {
					$newObj->$setter($value);
				}
			}
		}
		return $newObj;
	}

	/**
	 * Do setter method
	 *
	 * @param mixed $target the object which owns the setter method
	 * @param string $setter setter method name
	 * @param mixed $value the value set
	 * @param null|mixed $default default value
	 */
	public static function doSetter($target, $setter, $value, $default = null)
	{
		if (!is_null($value)) {
			$value = $value === 'null' ? null : $value;
			$target->$setter($value);
		} else {
			if (!is_null($default)) {
				$target->$setter($default);
			}
		}
	}
}